﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Reflection;
using System.Data;
using Portal.Workflow.Model;
using Portal.Core;
using Portal.Web.Utility;

namespace Portal.Workflow.Utilities
{
    public class ProcessCommand
    {
        public static string ServiceId
        {
            get
            {
                return "ProcessCommand";
            }
        }

        public static IProcessCommand[] LoadAssembly(string filename)
        {
            ArrayList ArrayListModules = new ArrayList();
            Assembly a = Assembly.LoadFrom(filename);
            if (a == null) throw new System.Exception("Assembly " + filename + " not found or not valid");
            foreach (Module mod in a.GetLoadedModules())
            {
                foreach (Type ty in mod.GetTypes())
                {
                    foreach (Type intf in ty.GetInterfaces())
                    {
                        if (intf == typeof(IProcessCommand))
                        {
                            try
                            {
                                IProcessCommand w = (IProcessCommand)a.CreateInstance(ty.FullName);
                                ArrayListModules.Add(w);

                            }
                            catch (System.Exception ex)
                            {
                                ex.Source = "";
                            }
                        }
                    }
                }
            }
            IProcessCommand[] ws = new IProcessCommand[ArrayListModules.Count];
            for (int iIndex = 0; iIndex < ArrayListModules.Count; iIndex++)
            {
                ws[iIndex] = (IProcessCommand)ArrayListModules[iIndex];
            }
            return ws;
        }


        public static IProcessCommand[] LoadAssembly(string filename,string FunctionClass)
        {
            ArrayList ArrayListModules = new ArrayList();
            Assembly a = Assembly.LoadFrom(filename);
            if (a == null) throw new System.Exception("Assembly " + filename + " not found or not valid");
            foreach (Module mod in a.GetLoadedModules())
            {
                foreach (Type ty in mod.GetTypes())
                {
                    foreach (Type intf in ty.GetInterfaces())
                    {
                        if (intf == typeof(IProcessCommand))
                        {
                            try
                            {
                                if(ty.FullName.ToLower().Equals(FunctionClass.ToLower()))
                                {
                                    IProcessCommand w = (IProcessCommand)a.CreateInstance(ty.FullName);
                                    ArrayListModules.Add(w);
                                    break;
                                }
                            }
                            catch (System.Exception ex)
                            {
                                ex.Source = "";
                            }
                        }
                    }
                }
            }
            IProcessCommand[] ws = new IProcessCommand[ArrayListModules.Count];
            for (int iIndex = 0; iIndex < ArrayListModules.Count; iIndex++)
            {
                ws[iIndex] = (IProcessCommand)ArrayListModules[iIndex];
            }
            return ws;
        }

        public static IProcessCommand[] LoadProcessCommands(string DllPath)
        {
            string[] Files = System.IO.Directory.GetFiles(DllPath, "*.dll");
            ArrayList ArrayListServives = new ArrayList();
            for (int iIndex = 0; iIndex < Files.Length; iIndex++)
            {
                try
                {
                    string FileDll = Files[iIndex];
                    IProcessCommand[]
                        asms = LoadAssembly(FileDll);
                    for (int jIndex = 0; jIndex < asms.Length; jIndex++)
                    {
                        ArrayListServives.Add(asms[jIndex]);
                    }
                }
                catch (System.Exception ex)
                {
                    ex.Source = "";
                }
            }
            IProcessCommand[] WebParts = new IProcessCommand[ArrayListServives.Count];
            for (int iIndex = 0; iIndex < ArrayListServives.Count; iIndex++)
            {
                WebParts[iIndex] = (IProcessCommand)ArrayListServives[iIndex];
            }
            return WebParts;
        }


        public static IProcessCommand[] LoadProcessCommands(string DllPath,string FunctionClass)
        {
            string[] Files = System.IO.Directory.GetFiles(DllPath, "*.dll");
            ArrayList ArrayListServives = new ArrayList();
            for (int iIndex = 0; iIndex < Files.Length; iIndex++)
            {
                try
                {
                    string FileDll = Files[iIndex];
                    IProcessCommand[]
                        asms = LoadAssembly(FileDll, FunctionClass);
                    for (int jIndex = 0; jIndex < asms.Length; jIndex++)
                    {
                        ArrayListServives.Add(asms[jIndex]);
                    }
                }
                catch (System.Exception ex)
                {
                    ex.Source = "";
                }
            }
            IProcessCommand[] WebParts = new IProcessCommand[ArrayListServives.Count];
            for (int iIndex = 0; iIndex < ArrayListServives.Count; iIndex++)
            {
                WebParts[iIndex] = (IProcessCommand)ArrayListServives[iIndex];
            }
            return WebParts;
        }

        public static void Process(
            WsInParamCls oWsInParamCls, 
            ref WsReturnParamCls oWsReturnParamCls)
        {
            if (string.IsNullOrEmpty(oWsInParamCls.SiteId))
            {
                throw new Exception("Chưa xác định SiteId! Xin cấu hình ở client!");
            }
            SiteParam OSiteParam = WebEnvironments.CreateSiteParam(oWsInParamCls.SiteId);
            
            IProcessCommand[] ProcessCommands = null;
            if (String.IsNullOrEmpty(oWsInParamCls.CommandDll) == false)
            {
                if (String.IsNullOrEmpty(oWsInParamCls.FunctionClass))
                {
                    ProcessCommands = LoadAssembly(oWsInParamCls.DllPath + "\\" + oWsInParamCls.CommandDll);
                }
                else
                {
                    ProcessCommands = LoadAssembly(oWsInParamCls.DllPath + "\\" + oWsInParamCls.CommandDll, oWsInParamCls.FunctionClass);
                }
            }
            else
            {
                ProcessCommands = LoadProcessCommands(oWsInParamCls.DllPath);
            }
            
            for (int iIndex = 0; iIndex < ProcessCommands.Length; iIndex++)
            {
                bool Done = ProcessCommands[iIndex].Process(oWsInParamCls, ref oWsReturnParamCls);

                if (Done)
                {
                    return;
                }
            }

            string MsgText = oWsInParamCls.Command.ToString()+": Command not handler!";
            throw new Exception(MsgText);
        }
    }
}
